home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
recvattach.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
15KB
|
609 lines
/*
* Copyright (C) 1996,1997 Michael R. Elkins <me@cs.hmc.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mutt.h"
#include "mutt_curses.h"
#include "mutt_menu.h"
#include "rfc1524.h"
#include "mime.h"
#include "mailbox.h"
#include "state.h"
#include "attach.h"
#ifdef _PGPPATH
#include "pgp.h"
#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
static ATTACHPTR *gen_attach_list (BODY *m, int level, int compose)
{
ATTACHPTR *top = NULL, *end = NULL, *new;
while (m)
{
if (m->type == TYPEMULTIPART && m->parts)
{
if (top)
end->next = gen_attach_list (m->parts, level, compose);
else
end = top = gen_attach_list (m->parts, level, compose);
while (end->next)
end = end->next;
}
else
{
new = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
new->content = m;
new->level = level;
if (top)
{
end->next = new;
end = new;
}
else
top = end = new;
/* We don't support multipart messages in the compose menu yet */
if (!compose && m->type == TYPEMESSAGE &&
(!strcasecmp (m->subtype, "rfc822") ||
!strcasecmp (m->subtype, "news")) &&
is_multipart (m->parts))
{
end->next = gen_attach_list (m->parts, level + 1, compose);
while (end->next)
end = end->next;
}
}
m = m->next;
}
return (top);
}
void mutt_update_tree (ATTACHPTR **idx, short idxlen)
{
char buf[STRING];
char *s;
int x;
for (x = 0; x < idxlen; x++)
{
if (2 * (idx[x]->level + 2) < sizeof (buf))
{
if (idx[x]->level)
{
s = buf + 2 * (idx[x]->level - 1);
*s++ = (idx[x]->content->next) ? '\003' : '\001';
*s++ = '\004';
*s++ = '\007';
}
else
s = buf;
*s = 0;
}
if (idx[x]->tree)
{
if (strcmp (idx[x]->tree, buf) != 0)
{
safe_free ((void **) &idx[x]->tree);
idx[x]->tree = safe_strdup (buf);
}
}
else
idx[x]->tree = safe_strdup (buf);
if (2 * (idx[x]->level + 2) < sizeof (buf) && idx[x]->level)
{
s = buf + 2 * (idx[x]->level - 1);
*s++ = (idx[x]->content->next) ? '\005' : '\006';
*s++ = '\006';
}
}
}
ATTACHPTR **mutt_gen_attach_list (BODY *cur, short *idxlen,
short *idxmax, int compose)
{
ATTACHPTR *list, *plist;
ATTACHPTR **idx;
plist = list = gen_attach_list (cur, 0, compose);
idx = (ATTACHPTR **) safe_malloc (sizeof (ATTACHPTR *) * (*idxmax = 5));
for (*idxlen = 0; plist; (*idxlen)++, plist = plist->next)
{
if (*idxlen == *idxmax)
safe_realloc ((void **) &idx, sizeof (ATTACHPTR *) * (*idxmax += 5));
idx[*idxlen] = plist;
}
mutt_update_tree (idx, *idxlen);
return (idx);
}
void attach_entry (char *b, size_t blen, MUTTMENU *menu, int num)
{
char t[SHORT_STRING];
char s[SHORT_STRING];
char size[SHORT_STRING];
ATTACHPTR **idx = (ATTACHPTR **) menu->data;
BODY *m;
m = idx[num]->content;
s[0] = 0;
if (m->type == TYPEMESSAGE && (!strcasecmp ("rfc822", m->subtype) ||
!strcasecmp ("news", m->subtype)) && MsgFmt[0])
_mutt_make_string (s, sizeof (s), MsgFmt, m->hdr, M_FORCESUBJ);
mutt_pretty_size (size, sizeof (size), m->length);
snprintf (t, sizeof (t), "[%.7s/%.10s, %.6s, %s]",
TYPE (m->type), m->subtype, ENCODING (m->encoding), size);
snprintf (b, blen, " %c %2d %-34.34s %s%s",
m->tagged ? '*' : ' ',
num + 1,
t,
idx[num]->tree ? idx[num]->tree : "",
s[0] ? s : (m->description ? m->description :
(m->filename ? m->filename : "<no description>")));
}
int mutt_tag_attach (MUTTMENU *menu, int n)
{
return (((ATTACHPTR **) menu->data)[n]->content->tagged = !((ATTACHPTR **) menu->data)[n]->content->tagged);
}
static void mutt_query_save_attachment (FILE *fp, BODY *body)
{
char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
if (fp && body->filename)
strfcpy (buf, body->filename, sizeof (buf));
else
buf[0] = 0;
if (mutt_get_field ("Save to file: ", buf, sizeof (buf), M_FILE | M_CLEAR) != 0 || !buf[0])
return;
mutt_expand_path (buf, sizeof (buf));
if (mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), 0))
return;
mutt_message ("Saving...");
if (mutt_save_attachment (fp, body, tfile, 0) == 0)
mutt_message ("Attachment saved.");
}
void mutt_save_attachment_list (FILE *fp, int tag, BODY *top)
{
for (; top; top = top->next)
{
if (!tag || top->tagged)
mutt_query_save_attachment (fp, top);
else if (top->parts)
mutt_save_attachment_list (fp, 1, top->parts);
if (!tag)
return;
}
}
static void
mutt_query_pipe_attachment (char *command, FILE *fp, BODY *body, int filter)
{
char tfile[_POSIX_PATH_MAX];
char warning[STRING+_POSIX_PATH_MAX];
if (filter)
{
snprintf (warning, sizeof (warning),
"WARNING! You are about to overwrite %s, continue?",
body->filename);
if (mutt_yesorno (warning, M_NO) != M_YES)
return;
mutt_mktemp (tfile);
}
else
tfile[0] = 0;
if (mutt_pipe_attachment (fp, body, command, tfile))
{
if (filter)
{
mutt_unlink (body->filename);
mutt_rename_file (tfile, body->filename);
mutt_update_encoding (body);
mutt_message ("Attachment filtered.");
}
}
else
{
if (filter && tfile[0])
mutt_unlink (tfile);
}
}
static void
pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter)
{
for (; top; top = top->next)
{
if (!tag || top->tagged)
mutt_query_pipe_attachment (command, fp, top, filter);
else if (top->parts)
pipe_attachment_list (command, fp, tag, top->parts, filter);
if (!tag)
break;
}
}
void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
{
char buf[SHORT_STRING];
if (fp)
filter = 0; /* sanity check: we can't filter in the recv case yet */
buf[0] = 0;
if (mutt_get_field ((filter ? "Filter through: " : "Pipe to: "),
buf, sizeof (buf), 0) != 0 || !buf[0])
return;
mutt_expand_path (buf, sizeof (buf));
pipe_attachment_list (buf, fp, tag, top, filter);
}
static void print_attachment_list (FILE *fp, int tag, BODY *top)
{
for (; top; top = top->next)
{
if (!tag || top->tagged)
mutt_print_attachment (fp, top);
else if (top->parts)
mutt_print_attachment_list (fp, tag, top->parts);
if (!tag)
return;
}
}
void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
{
if (query_quadoption (OPT_PRINT, tag ? "Print tagged attachment(s)?" : "Print attachment?") != M_YES)
return;
print_attachment_list (fp, tag, top);
}
int mutt_is_message_type (int type, char *subtype)
{
if (type != TYPEMESSAGE)
return 0;
if (strcasecmp (subtype, "rfc822") == 0 || strcasecmp (subtype, "news") == 0)
return 1;
return 0;
}
static void
bounce_attachment_list (ADDRESS *adr, int tag, BODY *body, HEADER *hdr)
{
for (; body; body = body->next)
{
if (!tag || body->tagged)
{
if (!mutt_is_message_type (body->type, body->subtype))
{
mutt_error ("You may only bounce message/rfc822 parts.");
continue;
}
body->hdr->msgno = hdr->msgno;
mutt_bounce_message (body->hdr, adr);
}
else if (body->parts)
bounce_attachment_list (adr, tag, body->parts, hdr);
if (!tag)
break;
}
}
static void query_bounce_attachment (int tag, BODY *top, HEADER *hdr)
{
c